/*
 * =================================================================
 *
 *            Filename:    TimerAgent.h
 *
 *         Description:    timer agent base class
 *
 *             Version:    v1.0
 *             Created:    2015-11-23 04:25
 *           Reversion:    none
 *            Compiler:    g++
 *            
 *              Author:    wangjin, 836792834@qq.com
 * 
 * ==================================================================
 */

#include "common/comm/Agent.h"
#include "common/comm/EpollEvent.h"
#include "TimerId.h"

#include <sys/timerfd.h>
#include <stdlib.h>

#include <stdexcept>

#ifndef TIMERAGENT_H_
#define TIMERAGENT_H_
class TimerAgent : public Agent {
public:
    TimerAgent( ) {
        
    }
    
    virtual ~TimerAgent() {
         
    }

    virtual void init( struct timespec &start_time, struct timespec &interval_time ) {
        if( m_timer.GenerateTimerFd() == FAILED ) 
            throw std::runtime_error("TimerAgent init error!");

        if( m_timer.SetIntervalTime( start_time, interval_time ) == FAILED) 
            throw std::runtime_error("TimerAgent init error!");

        m_epollEvent.setFd( m_timer.timer_fd() );
        m_epollEvent.setHandlerID( Agent::getID() );      
        m_epollEvent.registerREvent();
    }

    virtual void update(struct timespec &start_time, struct timespec &interval_time)
    {
        if( m_timer.SetIntervalTime( start_time, interval_time ) == FAILED)
            throw std::runtime_error("TimerAgent init error!"); 
    }

    virtual int sendData() {
        return SUCCESSFUL;
    }

    virtual int recvData() {
        uint64_t timeCount;

        if ( m_timer.ReadTimerCount( timeCount ) < 0 ) {
            perror("recv Data error!");
            return FAILED;
        }

        timerReadBack( timeCount );
        return SUCCESSFUL;
    }

    //shoud be overwrited by derive classes
    virtual void timerReadBack( uint64_t timeCount ) {
         
    }

    TimerId getTimer()const {
        return m_timer;
    }

    void recycler() {
        if( m_timer.Close() != 0 ) {
            throw std::runtime_error("close timer error!");
        }
    }
    

private:
    TimerId m_timer;
    EpollEvent m_epollEvent;
};

#endif

